package com.lucifer.treasure.enchant.effect;

import com.mojang.serialization.MapCodec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import net.fabricmc.fabric.api.entity.event.v1.ServerLivingEntityEvents;
import net.minecraft.enchantment.EnchantmentEffectContext;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.enchantment.EnchantmentLevelBasedValue;
import net.minecraft.enchantment.effect.EnchantmentEntityEffect;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EquipmentSlot;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.effect.StatusEffectInstance;
import net.minecraft.entity.effect.StatusEffects;
import net.minecraft.item.ItemStack;
import net.minecraft.particle.ParticleTypes;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.sound.SoundCategory;
import net.minecraft.sound.SoundEvents;
import net.minecraft.text.Text;
import net.minecraft.util.math.Vec3d;

public record LastStandEnchantmentEffect(EnchantmentLevelBasedValue survival) implements EnchantmentEntityEffect {
    public static final MapCodec<LastStandEnchantmentEffect> CODEC = RecordCodecBuilder.mapCodec(instance ->
            instance.group(
                    EnchantmentLevelBasedValue.CODEC.fieldOf("survival").forGetter(LastStandEnchantmentEffect::survival)
            ).apply(instance, LastStandEnchantmentEffect::new)
    );

    // 配置常量
    private static final int BASE_XP_COST = 30; // 1级基础经验消耗
    private static final int ABSORPTION_DURATION = 600; // 30秒吸收效果
    private static final int COOLDOWN_TICKS = 1200; // 60秒冷却

    public static void initialize() {
        // 监听伤害事件，在伤害发生前拦截致命伤害
        ServerLivingEntityEvents.ALLOW_DAMAGE.register((entity, source, amount) -> {
            // 检查是否会致命，如果会则尝试触发LastStand
            if (entity instanceof ServerPlayerEntity player) {
                if (entity.getHealth() - amount <= 0) {
                    return !handleLastStand(player, amount);
                }
            }
            return true; // 允许正常伤害
        });
    }

    /**
     * 处理背水一战逻辑
     *
     * @return true 如果成功触发LastStand，false 如果未触发
     */
    private static boolean handleLastStand(ServerPlayerEntity player, float damage) {
        int level = getLastStandLevel(player);
        if (level <= 0) {
            return false;
        }

        // 检查冷却
        ItemStack leggings = player.getEquippedStack(EquipmentSlot.LEGS);
        if (leggings.isEmpty() || player.getItemCooldownManager().isCoolingDown(leggings.getItem())) {
            return false;
        }

        // 计算经验消耗（等级越高消耗越少）
        int xpCost = Math.max(1, BASE_XP_COST / level);
        int currentXp = getTotalExperience(player);

        if (currentXp < xpCost) {
            return false; // 经验不足
        }

        // 成功触发LastStand
        // 设置生命值为1
        player.setHealth(1.0f);

        // 消耗经验
        removeExperience(player, xpCost);

        // 给予吸收效果
        int absorptionLevel = level - 1; // 1级=0级吸收，2级=1级吸收
        StatusEffectInstance absorptionEffect = new StatusEffectInstance(StatusEffects.ABSORPTION, ABSORPTION_DURATION, absorptionLevel);
        player.addStatusEffect(absorptionEffect);

        // 设置冷却
        player.getItemCooldownManager().set(leggings.getItem(), COOLDOWN_TICKS);

        // 播放音效
        player.getWorld().playSound(null, player.getX(), player.getY(), player.getZ(),
                SoundEvents.ITEM_TOTEM_USE, SoundCategory.PLAYERS,
                1.0f, 0.8f);

        // 生成粒子效果
        ServerWorld world = player.getServerWorld();
        world.spawnParticles(ParticleTypes.TOTEM_OF_UNDYING,
                player.getX(), player.getY() + 1.0, player.getZ(),
                30, // 粒子数量
                0.5, 1.0, 0.5, // 扩散范围
                0.1 // 初始速度
        );

        // 额外的金色粒子效果
        world.spawnParticles(ParticleTypes.CRIT,
                player.getX(), player.getY() + 0.5, player.getZ(),
                15, // 粒子数量
                0.3, 0.3, 0.3, // 扩散范围
                0.1 // 初始速度
        );

        // 发送激活消息
        player.sendMessage(Text.translatable("enchantment.lucifer_treasure.laststand.activated"), true);

        return true;
    }

    /**
     * 获取实体的LastStand附魔等级
     */
    private static int getLastStandLevel(LivingEntity entity) {
        ItemStack leggings = entity.getEquippedStack(EquipmentSlot.LEGS);
        if (leggings.isEmpty()) {
            return 0;
        }

        var enchantments = EnchantmentHelper.getEnchantments(leggings);
        return enchantments.getEnchantments().stream()
                .filter(entry -> {
                    if (entry.getKey().isPresent()) {
                        return entry.getKey().get().getValue().toString().equals("lucifer_treasure:laststand");
                    }
                    return false;
                })
                .mapToInt(entry -> enchantments.getLevel(entry))
                .max()
                .orElse(0);
    }

    /**
     * 获取玩家总经验值
     */
    private static int getTotalExperience(ServerPlayerEntity player) {
        int totalXp = Math.round(player.experienceProgress * getExperienceToNextLevel(player.experienceLevel));

        // 计算当前等级所需的经验
        for (int level = 0; level < player.experienceLevel; level++) {
            totalXp += getExperienceToNextLevel(level);
        }

        return totalXp;
    }

    /**
     * 获取指定等级升级所需经验
     */
    private static int getExperienceToNextLevel(int level) {
        if (level >= 30) {
            return 112 + (level - 30) * 9;
        } else if (level >= 15) {
            return 37 + (level - 15) * 5;
        } else {
            return 7 + level * 2;
        }
    }

    /**
     * 移除玩家指定数量的经验
     */
    private static void removeExperience(ServerPlayerEntity player, int amount) {
        int totalXp = getTotalExperience(player);
        totalXp = Math.max(0, totalXp - amount);

        // 重新设置经验
        player.experienceLevel = 0;
        player.experienceProgress = 0;
        player.totalExperience = 0;

        // 逐步添加经验到正确的等级
        while (totalXp > 0) {
            int xpToNext = getExperienceToNextLevel(player.experienceLevel);
            if (totalXp >= xpToNext) {
                totalXp -= xpToNext;
                player.experienceLevel++;
                player.totalExperience += xpToNext;
            } else {
                player.experienceProgress = (float) totalXp / xpToNext;
                player.totalExperience += totalXp;
                break;
            }
        }
    }

    @Override
    public void apply(ServerWorld world, int level, EnchantmentEffectContext context, Entity target, Vec3d pos) {
        // 主要逻辑在事件监听器中处理
        // 这里可以添加其他效果
        if (target instanceof LivingEntity living) {
            // 添加微妙的粒子效果表示附魔存在
            world.spawnParticles(ParticleTypes.ENCHANT,
                    target.getX(), target.getY() + 0.5, target.getZ(),
                    2, 0.2, 0.2, 0.2, 0.01);
        }
    }

    @Override
    public MapCodec<? extends EnchantmentEntityEffect> getCodec() {
        return CODEC;
    }
} 